﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Metadata;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using Aribaccio;
using Aribaccio.Device;
using BDPAutodetect.DataService;
using BDPAutodetect.Device;
using BDPAutodetect.Models;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BDPAutodetect.Mgrcore
{
    /// <summary>
    /// 指标和从机设备协议管理
    /// </summary>
    public partial class TargetSlaveManager : BaseManager
    {
        /// <summary>
        /// 基础数据操作实例
        /// </summary>
        protected IDataServiceBasic DataService { get; set; }
        /// <summary>
        /// 从机设备管理实例
        /// </summary>
        protected SlaveManager SlaveMgr { get; set; }
        /// <summary>
        /// 工位管理实例
        /// </summary>
        protected StationManager StationMgr { get; set; }

        /// <summary>
        /// 指标数据集
        /// </summary>
        public List<MTarget> Targets { get; protected set; }
        /// <summary>
        /// 指标数据集[客户机端]
        /// </summary>
        public List<MTarget> TargetCustomers { get; protected set; }
        /// <summary>
        /// 指标从机设备协议数据集
        /// </summary>
        public List<MTargetSlave> TargetSlaves { get; protected set; }
        /// <summary>
        /// 指标k客户机端设备协议数据集
        /// </summary>
        public List<MTargetSlave> TargetSlaveCustomers { get; protected set; }

        /// <summary>
        /// 是否有效存在指标信息
        /// </summary>
        public bool IsValid => this.Targets != null && this.Targets.Count > 0;
        /// <summary>
        /// 是否有效存在客户机端指标信息
        /// </summary>
        public bool IsValidCustomer => this.TargetCustomers != null && this.TargetCustomers.Count > 0;
        /// <summary>
        /// 是否有效存在指标从机设备协议信息
        /// </summary>
        public bool IsValidSlave => this.TargetSlaves != null && this.TargetSlaves.Count > 0;

        /// <summary>
        /// 构造函数[注入]
        /// </summary>
        public TargetSlaveManager(IDataServiceBasic argDataService, SlaveManager argSlaveManager, StationManager argStationManager)
            : base("指标协议管理中心")
        {
            this.DataService = argDataService;
            this.SlaveMgr = argSlaveManager;
            this.StationMgr = argStationManager;
            this.Targets = new List<MTarget>();
            this.TargetCustomers = new List<MTarget>();
            this.TargetSlaves = new List<MTargetSlave>();
            this.TargetSlaveCustomers = new List<MTargetSlave>();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public override async Task Initialize()
        {
            //基础指标
            var results = this.InitializeTarget();
            await results.ConfigureAwait(false);
            //指标从机协议
            results = this.InitializeTargetSlave();
            await results.ConfigureAwait(false);
        }

        /// <summary>
        /// 初始化指标数据
        /// </summary>
        protected async Task InitializeTarget()
        {
            if (this.IsValid) return;
            if (this.Targets == null) this.Targets = new List<MTarget>();
            if (this.TargetCustomers == null) this.TargetCustomers = new List<MTarget>();
            //获取数据库数据
            var resultDatas = this.DataService.SelectModelItemsTask<TBasicTarget>();
            await resultDatas.ConfigureAwait(false);
            if (resultDatas == null || !resultDatas.Result.ResultState || resultDatas.Result.Data == null) return;

            //先排序,在循环添加到集合
            var orderTargets = resultDatas.Result.Data.OrderBy(v => v.Category).OrderBy(v => v.ID).ToList();
            foreach (var targetItem in orderTargets)
            {
                if (targetItem == null) continue;
                DeviceTargetType targetType = targetItem.Code.ToEnum<DeviceTargetType>();
                DeviceType targetCategory = targetItem.Category.ToEnum<DeviceType>();
                if (targetType == DeviceTargetType.None || targetCategory == DeviceType.None) continue;

                //获取指标集合，添加指标
                var targetCategoryData = DeviceTypeTable.GetDeviceTypeData(targetCategory);
                int nSerialNoNext = this.Targets.Count > 0 ? (this.Targets.Last().SerialNo + 1) : 1;
                var target = new MTarget(targetItem.ID, targetItem.Code, targetItem.Name)
                {
                    SerialNo = nSerialNoNext,
                    TargetType = targetType,
                    TargetCategory = targetCategory,
                    TargetCategoryData = targetCategoryData
                };
                //单独存储客户端指标
                if (targetCategory == DeviceType.Customer)
                {
                    this.TargetCustomers.Add(target);
                }
                this.Targets.Add(target);
            }
        }

        /// <summary>
        /// 初始化指标从机设备协议
        /// </summary>
        /// <returns></returns>
        protected async Task InitializeTargetSlave()
        {
            if (!this.IsValid || this.IsValidSlave) return;
            if (this.TargetSlaves == null) this.TargetSlaves = new List<MTargetSlave>();

            //初始化更新数据
            var result = this.UpdateDatas();
            await result.ConfigureAwait(false);
        }

        /// <summary>
        /// 更新指标从机设备协议数据集
        /// </summary>
        /// <param name="argQueryData">为空，表示查询全部</param>
        /// <returns></returns>
        protected async Task UpdateDatas(QueryTargetSlaveDto? argQueryData = null)
        {
            //获取数据库数据
            var resultDatas = argQueryData == null
                ? this.DataService.SelectModelItemsTask<TTargetSlave>()
                : this.DataService.SelectModelItemsTask<TTargetSlave>(v => v.StationID == argQueryData.StationID && v.SlaveID == argQueryData.SlaveID && v.Category == argQueryData.Category);
            await resultDatas.ConfigureAwait(false);
            if (resultDatas == null || resultDatas.Result == null || !resultDatas.Result.ResultState || resultDatas.Result.Data == null) return;

            var orderDatas = resultDatas.Result.Data.OrderBy(v => v.ID);
            foreach (var item in orderDatas)
            {
                MTarget? target = this.GetTarget(item.TargetID);
                if (target == null) continue;

                MStation station = this.StationMgr.GetStation(item.StationID) ?? new MStation();
                MSlave slave = this.SlaveMgr.GetSlave(item.SlaveID) ?? new MSlave();
                MTarget? targetMap = this.GetTarget(item.TargetMapID);
                //创建数据
                MTargetSlave targetSlave = new MTargetSlave(item.ID, station, slave, target, targetMap)
                {
                    SlaveCommand = item.SlaveCommand,
                    CheckCommand = item.CheckCommand,
                    SlaveAddress = item.SlaveAddress,
                    SlaveFuncCode = item.SlaveFuncCode,
                    RegisterAddress = item.RegisterAddress,
                    CheckMode = item.CheckMode.ToEnum<DeviceCheck>(),
                    DataType = item.DataType.ToEnum<DataType>(),
                    DataUnit = item.DataUnit.ToEnum<DataUnit>(),
                    DisplayUnit = item.DisplayUnit.ToEnum<DataUnit>(),
                    DataPrecision = item.DataPrecision,
                    SendWaitStatus = item.SendWaitFlag.ToEnum<ExecuteStatus>(),
                    DetectWaitStatus = item.DetectWaitFlag.ToEnum<ExecuteStatus>(),
                    PermissionStatus = item.PermissionFlag.ToEnum<ExecuteStatus>()
                };
                //单独存储客户端指标设备协议
                if (target.TargetCategory == DeviceType.Customer)
                {
                    this.TargetSlaveCustomers.Add(targetSlave);
                }
                this.TargetSlaves.Add(targetSlave);
            }
        }

        public async Task<bool> InsertTargetSlave(QueryTargetSlaveDto argQueryData)
        {
            //检测是否已经存在
            var datas = this.GetTargetSlaves(argQueryData);
            if (datas != null && datas.Count > 0) return false;

            //获取指标
            var targets = this.GetTargets(argQueryData.DeviceType);
            if (targets == null || targets.Count <= 0) return false;
            //循环添加到数据库
            bool bPass = true;
            foreach (var item in targets)
            {
                Task<Result> result = this.DataService.InsertTask(new TTargetSlave()
                {
                    TargetID = item.ID,
                    StationID = argQueryData.StationID,
                    SlaveID = argQueryData.SlaveID,
                    Category = argQueryData.Category
                });
                await result.ConfigureAwait(false);
                if (result == null || result.Result == null || !result.Result.ResultState)
                {
                    bPass = false;
                    break;
                }
            }
            if (bPass)
            {
                //获取数据库数据，更新缓存
                var resultUpdate = this.UpdateDatas(argQueryData);
                await resultUpdate.ConfigureAwait(false);
            }
            else
            {
                //执行删除数据
                var resultDelete = this.DataService.DeleteWhereTask<TTargetSlave>(v => v.StationID == argQueryData.StationID && v.SlaveID == argQueryData.SlaveID && v.Category == argQueryData.Category);
                await resultDelete.ConfigureAwait(false);
            }
            return bPass;
        }

        /// <summary>
        /// 删除从机设备协议数据
        /// </summary>
        /// <returns></returns>
        public async Task<bool> DeleteTargetSlave(QueryTargetSlaveDto argQueryData)
        {
            if (argQueryData == null) return false;

            Task<Result> result = this.DataService.DeleteWhereTask<TTargetSlave>(v => v.StationID == argQueryData.StationID && v.SlaveID == argQueryData.SlaveID && v.Category == argQueryData.Category);
            await result.ConfigureAwait(false);
            if (result == null || result.Result == null || !result.Result.ResultState) return false;

            //删除成功，删除缓存数据
            if (result != null && result.Result.ResultState)
            {
                var datas = this.GetTargetSlaves(argQueryData);
                foreach (var data in datas)
                {
                    this.TargetSlaves.Remove(data);
                }
            }
            return true;
        }

        /// <summary>
        /// 克隆从机设备协议数据
        /// </summary>
        /// <param name="argSourceData">需要克隆条件源数据</param>
        ///  <param name="argCloneData">需要克隆条件数据</param>
        /// <returns></returns>
        public async Task<bool> CloneTargetSlave(QueryTargetSlaveDto argSourceData, QueryTargetSlaveDto argCloneData)
        {
            // 检测是否已经存在
            var sourceDatas = this.GetTargetSlaves(argSourceData);
            if (sourceDatas == null || sourceDatas.Count <= 0) return false;

            //循环添加到数据库
            bool bPass = true;
            foreach (var item in sourceDatas)
            {
                if (item == null) continue;
                var CloneItem = item.CloneTData();
                CloneItem.ID = 0;
                CloneItem.StationID = argCloneData.StationID;
                CloneItem.SlaveID = argCloneData.SlaveID;
                var result = this.DataService.InsertTask(CloneItem);
                await result.ConfigureAwait(false);
                if (result == null || result.Result == null || !result.Result.ResultState)
                {
                    bPass = false;
                    break;
                }
            }
            if (bPass)
            {
                //获取数据库数据，更新缓存
                var resultUpdate = this.UpdateDatas(argCloneData);
                await resultUpdate.ConfigureAwait(false);
            }
            else
            {
                //执行删除数据
                var resultDelete = this.DataService.DeleteWhereTask<TTargetSlave>(v => v.StationID == argCloneData.StationID && v.SlaveID == argCloneData.SlaveID && v.Category == argCloneData.Category);
                await resultDelete.ConfigureAwait(false);
            }
            return bPass;
        }

        /// <summary>
        /// 更新指标从机设备协议数据
        /// </summary>
        /// <param name="argTargetSlave">指标从机设备协议数据</param>
        /// <returns></returns>
        public async Task<bool> UpdateTargetSlave(MTargetSlave argTargetSlave)
        {
            Task<Result> result = this.DataService.UpdateWhereTask<TTargetSlave>(argTargetSlave.CloneTData(), v => v.ID == argTargetSlave.ID);
            await result.ConfigureAwait(false);
            if (result == null || result.Result == null || !result.Result.ResultState) return false;
            //更新缓存
            var targetSlave = this.TargetSlaves.First(v => v.ID == argTargetSlave.ID);
            if (targetSlave != null)
            {
                targetSlave.Station = argTargetSlave.Station;
                targetSlave.Slave = argTargetSlave.Slave;
                targetSlave.Target = argTargetSlave.Target;
                targetSlave.TargetMap = argTargetSlave.TargetMap;
                targetSlave.SlaveCommand = argTargetSlave.SlaveCommand;
                targetSlave.CheckCommand = argTargetSlave.CheckCommand;
                targetSlave.SlaveAddress = argTargetSlave.SlaveAddress;
                targetSlave.SlaveFuncCode = argTargetSlave.SlaveFuncCode;
                targetSlave.RegisterAddress = argTargetSlave.RegisterAddress;
                targetSlave.CheckMode = argTargetSlave.CheckMode;
                targetSlave.DataType = argTargetSlave.DataType;
                targetSlave.DataUnit = argTargetSlave.DataUnit;
                targetSlave.DisplayUnit = argTargetSlave.DisplayUnit;
                targetSlave.DataPrecision = argTargetSlave.DataPrecision;
                targetSlave.SendWaitStatus = argTargetSlave.SendWaitStatus;
                targetSlave.DetectWaitStatus = argTargetSlave.DetectWaitStatus;
                targetSlave.PermissionStatus = argTargetSlave.PermissionStatus;
            }
            return true;
        }

        /// <summary>
        /// 更新指标
        /// </summary>
        /// <param name="argTarget">指标数据</param>
        /// <returns></returns>
        public async Task<bool> UpdateTarget(MTarget argTarget)
        {
            Task<Result> result = this.DataService.UpdateWhereTask<TBasicTarget>(argTarget.CloneTData(), v => v.ID == argTarget.ID);
            await result.ConfigureAwait(false);
            if (result == null || result.Result == null || !result.Result.ResultState) return false;

            var target = this.Targets.First(v => v.ID == argTarget.ID);
            if (target != null)
            {
                target.Code = argTarget.Code;
                target.Name = argTarget.Name;
                target.TargetType = argTarget.Code.ToEnum<DeviceTargetType>();
                target.TargetCategory = argTarget.TargetCategory;
                target.TargetCategoryData = DeviceTypeTable.GetDeviceTypeData(argTarget.TargetCategory);
            }
            return true;
        }


        /// <summary>
        /// 获取端指标信息
        /// </summary>
        /// <param name="argTargetID">指标ID</param>
        /// <returns></returns>
        public MTarget? GetTarget(int argTargetID)
        {
            if (!this.IsValid) return default;
            return this.Targets.FirstOrDefault(v => v.ID == argTargetID);
        }

        /// <summary>
        /// 获取客户机端指标信息
        /// </summary>
        /// <param name="argTargetID">指标ID</param>
        /// <returns></returns>
        public MTarget? GetTargetCustomer(int argTargetID)
        {
            if (!this.IsValidCustomer) return default;
            return this.TargetCustomers.FirstOrDefault(v => v.ID == argTargetID);
        }

        /// <summary>
        /// 获取种类指标数据集
        /// </summary>
        /// <param name="argTargetCategory">工位种类</param>
        /// <returns></returns>
        public List<MTarget>? GetTargets(DeviceType argTargetCategory)
        {
            if (!this.IsValid) return default;
            var targetList = this.Targets.Where(v => v.TargetCategory == argTargetCategory);
            return targetList != null ? targetList.ToList() : default;
        }

        /// <summary>
        /// 获取指标从机设备协议数据
        /// </summary>
        /// <param name="argQueryData">查询传输条件数据</param>
        /// <returns></returns>
        public List<MTargetSlave> GetTargetSlaves(DeviceType argTargetCategory)
        {
            if (!this.IsValidSlave) return new List<MTargetSlave>();
            var tSlaves = this.TargetSlaves.Where(v => v.Target.TargetCategory == argTargetCategory);
            return tSlaves != null ? tSlaves.ToList() : new List<MTargetSlave>();
        }

        /// <summary>
        /// 获取指标从机设备协议数据
        /// </summary>
        /// <param name="argQueryData">查询传输条件数据</param>
        /// <returns></returns>
        public List<MTargetSlave> GetTargetSlaves(QueryTargetSlaveDto argQueryData)
        {
            if (!this.IsValidSlave || argQueryData == null) return new List<MTargetSlave>();
            var tSlaves = this.TargetSlaves.Where(v => v.Slave.ID == argQueryData.SlaveID
                && v.Station.StationType == argQueryData.StationType
                && v.Target.TargetCategory == argQueryData.DeviceType);
            return tSlaves != null ? tSlaves.ToList() : new List<MTargetSlave>();
        }

        /// <summary>
        /// 获取指标从机设备协议数据
        /// </summary>
        /// <param name="argSlaveID"></param>
        /// <returns></returns>
        public List<MTargetSlave> GetTargetSlaveCustomer(int argSlaveID)
        {
            if (this.TargetSlaveCustomers == null || this.TargetSlaveCustomers.Count <= 0) return new List<MTargetSlave>();
            var tSlaves = this.TargetSlaveCustomers.Where(v => v.Slave.ID == argSlaveID);
            return tSlaves != null ? tSlaves.ToList() : new List<MTargetSlave>();
        }

        /// <summary>
        /// 获取指标检测信息
        /// </summary>
        /// <returns></returns>
        public List<MTargetDetectDto> GetTargetDetects()
        {
            List<MTargetDetectDto> resultDetects = new List<MTargetDetectDto>();
            if (!this.IsValidCustomer) return resultDetects;
            foreach (var targetItem in this.TargetCustomers)
            {
                resultDetects.Add(new MTargetDetectDto(targetItem));
            }
            return resultDetects;
        }

        /// <summary>
        /// 获取工位数据集
        /// </summary>
        /// <returns></returns>
        public List<MStation> GetStations()
        {
            return this.StationMgr.Stations;
        }

        /// <summary>
        /// 从机设备集
        /// </summary>
        /// <returns></returns>
        public List<MSlave> GetSlaves()
        {
            return this.SlaveMgr.Slaves;
        }
    }
}
